package com.loong.android.views;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.loong.android.views.adapter.ListAdapter;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.loong.android.R;
import com.loong.android.views.utils.Unit;
import com.loong.android.views.utils.ViewTemplate;
import com.loong.android.views.utils.ViewUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 下拉框
 */
public class SelectBox extends LonLinearLayout implements ViewTemplate {

    //下拉列表的内容
    private String listItemsData;
    //下拉列表项目内容的自定义分隔符
    private String listItemsDelimiter;
    private int optionItemLimitSize = -1;
    private int leftImgResId = -1;
    private boolean hideLeftImg = false;
    private int arrowResId = -1;
    private boolean hideArrow = false;
    private int presentMode = PresentMode.BELLOW_LEFT;
    private String mTextContent = "Spinner";
    private int mTextSize = 14;
    private int mTextColor = Color.parseColor("#FF333333");

    private int mViewWidth = 0;
    private int mViewHeight = 0;
    private int mPopupWidth = 0;
    private int mPopupHeight = 0;
    private boolean useCustomLayout = false;
    private LonLinearLayout rootView;
    private LonTextView tvTitle;
    private LonImageView imgLeft;
    private LonImageView imgArrow;
    private final PopupView popupView = new PopupView(getContext());
    private LonRelativeLayout popupRootView;
    private LonLinearLayout popupListContainer;
    private LonListView popupLonListView;
    private List<Item> itemDataList = new ArrayList<>();

    public SelectBox(@NonNull Context context) {
        super(context);
        initAttrs(context, null);
    }

    public SelectBox(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
    }

    public SelectBox(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        if (context == null) return;

        mTextSize = ViewUtils.sp2px(context, 14);
        int vLayoutId = -1;

        if (attrs != null) {
            @SuppressLint("CustomViewStyleable")
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Spinner);

            leftImgResId = ta.getResourceId(R.styleable.Spinner_leftImgSrc, leftImgResId);
            arrowResId = ta.getResourceId(R.styleable.Spinner_arrowSrc, arrowResId);
            hideLeftImg = ta.getBoolean(R.styleable.Spinner_hideLeftImg, hideLeftImg);
            hideArrow = ta.getBoolean(R.styleable.Spinner_hideArrow, hideArrow);

            String tvTextContent = ta.getString(R.styleable.Spinner_text);
            if(tvTextContent != null) mTextContent = tvTextContent;
            mTextSize = ta.getDimensionPixelSize(R.styleable.Spinner_textSize, mTextSize);
            mTextColor = ta.getColor(R.styleable.Spinner_textColor, mTextColor);

            optionItemLimitSize = ta.getInt(R.styleable.Spinner_optionItemLimitSize, optionItemLimitSize);
            presentMode = ta.getInt(R.styleable.Spinner_presentMode, presentMode);
            listItemsData = ta.getString(R.styleable.Spinner_listItems);
            listItemsDelimiter = ta.getString(R.styleable.Spinner_listItemsDelimiter);
            if (listItemsDelimiter == null) listItemsDelimiter = ",";

            ta.recycle();
        }
        initView(context, vLayoutId);
    }

    private void initView(Context context, int layoutId) {

        setPopupViewContent();

        useCustomLayout = layoutId >= 0;
        if (!useCustomLayout) layoutId = R.layout.loong_popup_spinner_default_view;
        View view = View.inflate(context, layoutId, this);

        if (!useCustomLayout) {
            rootView = view.findViewById(R.id.view_root);
            tvTitle = view.findViewById(R.id.tv_title);
            imgLeft = view.findViewById(R.id.img_left);
            imgArrow = view.findViewById(R.id.arrow);
            if(hideArrow) {
                imgArrow.visibility(View.GONE);
            }else {
                imgArrow.visibility(View.VISIBLE);
                if(arrowResId != -1) imgArrow.src(arrowResId);
            }
            if(hideLeftImg) {
                imgLeft.visibility(View.GONE);
            }else {
                imgLeft.visibility(View.VISIBLE);
                if(leftImgResId != -1) imgLeft.src(leftImgResId);
            }
            tvTitle.setText(mTextContent);
            tvTitle.textColor(mTextColor);
            tvTitle.textSize(Unit.PX, mTextSize);
            String[] stringItems = null;
            if (listItemsData != null) {
                try {
                    stringItems = listItemsData.split(listItemsDelimiter);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            List<Item> listItems = null;
            if(stringItems != null && stringItems.length > 0) {
                listItems = new ArrayList<>(stringItems.length);
                for (int i = 0; i < stringItems.length; i++) {
                    listItems.set(i, new Item(stringItems[i]));
                }
            }
            setListItems(listItems);
            rootView.setOnClickListener(v -> {
                if (popupView.isShowing()) {
                    closePopupView();
                } else {
                    openPopupView(presentMode);
                }
            });
        }

    }

    private void setPopupViewContent() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.loong_popup_spinner_options_list, null, false);
        popupRootView = view.findViewById(R.id.outer);
        popupRootView.setOnSizeChange(new LonView.SizeChangeCallback() {
            @Override
            public void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) {
                super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
                mPopupWidth = newWidth;
                mPopupHeight = newHeight;
            }
        });
        popupListContainer = view.findViewById(R.id.inner);
        popupLonListView = view.findViewById(R.id.list);
        ListAdapter adapter = new ListAdapter();
        popupLonListView.setAdapter(adapter);
        adapter.setEvent(new ListAdapter.Event() {
            @Override
            public int getItemCount(ListAdapter renderer) {
                return itemDataList.size();
            }

            @Override
            public View onGetItemView(ListAdapter adapter, int position, View itemView, ViewGroup parent) {
                View iv;
                if (itemView == null) {
                    iv = ViewUtils.toView(getContext(), R.layout.loong_popup_spinner_options_item, null);
                } else {
                    iv = itemView;
                }
                LonTextView lonTextView = ListAdapter.getViewById(iv, R.id.tv1);
                final Item item = itemDataList.get(position);
                if (lonTextView != null && item != null) {
                    lonTextView.text(item.getTitle());
                    lonTextView.setOnClick(new LonView.ClickCallback() {
                        @Override
                        public void onClick(View view) {
                            super.onClick(view);
                            callPopupListOnItemSelected(item, position);
                        }
                    });
                }
                return iv;
            }
        });
        popupView.setTouchable(true);
        popupView.setFocusable(true);
        popupView.setOutsideTouchable(true);
        popupView.setContentView(view);
        popupView.setDismissEvent(new PopupView.DismissEvent() {
            @Override
            public void onDismiss() {
                super.onDismiss();
                if(mItemSelectedEvent != null) mItemSelectedEvent.onPopupDismiss();
            }
        });
    }

    private void callPopupListOnItemSelected(Item item, int position) {
        if (tvTitle != null) tvTitle.text(item.getTitle());
        if(mItemSelectedEvent != null) mItemSelectedEvent.onItemSelected(item, position);
        closePopupView();
    }

    //region 自定义的方法

    /**
     * 获取默认视图的根视图
     */
    public LonLinearLayout getRootView() {
        return rootView;
    }

    /**
     * 获取默认视图的文本子视图，可通过该视图操作文本显示的样式
     */
    public LonTextView getTextView() {
        return tvTitle;
    }

    /**
     * 获取默认视图的左侧图片子视图，可通过该视图操作左侧图片的显示的样式
     */
    public LonImageView getLeftImg() {
        return imgLeft;
    }

    /**
     * 获取默认视图的右侧指针子视图，可通过该视图操作指针的显示的样式
     */
    public LonImageView getArrow() {
        return imgArrow;
    }

    /**
     * 取弹窗对象
     */
    public PopupView getPopupView() {
        return popupView;
    }

    /**
     * 取选项弹窗的根视图
     */
    public LonRelativeLayout getPopupRootView() {
        return popupRootView;
    }

    /**
     * 取选项弹窗的列表容器视图
     */
    public LonLinearLayout getPopupListContainer() {
        return popupListContainer;
    }

    /**
     * 取选项弹窗的列表框
     */
    public LonListView getPopupListView() {
        return popupLonListView;
    }

    /**
     * 设置选项数据
     * @param items 选项数据数组
     */
    public void setListItems(Item[] items) {
        if (popupLonListView == null) return;
        itemDataList = items != null ?  new ArrayList<>(Arrays.asList(items)) : new ArrayList<>();
        calcPopupViewSize();
    }

    /**
     * 设置选项数据
     * @param items 选项数据数组
     */
    public void setListItems(List<Item> items) {
        if (popupLonListView == null) return;
        itemDataList = items != null ?  new ArrayList<>(items) : new ArrayList<>();
        calcPopupViewSize();
    }

    private void calcPopupViewSize() {
        ListAdapter adapter = popupLonListView.getAdapter();
        int minWidth = ViewUtils.dp2px(getContext(), 64);
        int count = adapter.getCount();
        int itemCount = 0;
        int w = 0;
        int h = 0;
        for (int i = 0; i < count; i++) {
            if(optionItemLimitSize >= 0 && i >= optionItemLimitSize) break;
            View listItem = adapter.getView(i, null, this);
            listItem.measure(0, 0);
            w = Math.max(listItem.getMeasuredWidth(), w);
            if(optionItemLimitSize < 0 || i < optionItemLimitSize) {
                h += listItem.getMeasuredHeight();
            }
            itemCount++;
        }
        w = minWidth >= 0 && w < minWidth ? minWidth : w;
        h += itemCount > 1 ? popupLonListView.getDividerHeight() * (itemCount - 1) : 0;
        mPopupWidth = w + ViewUtils.dp2px(getContext(), 12);
        mPopupHeight = h + ViewUtils.dp2px(getContext(), 12);
        popupLonListView.setWidthHeight(w, optionItemLimitSize >= 0 ? h : -2);
    }

    /**
     * 显示选项弹窗
     * @param mode 模式，参考模式表：PresentMode类
     */
    public void openPopupView(int mode) {
        if (mode == PresentMode.BELLOW_RIGHT) {
            popupView.showAsDropDown(rootView, mViewWidth - mPopupWidth, 0);
        }
        else if (mode == PresentMode.BELLOW_CENTER) {
            popupView.showAsDropDown(rootView, (mViewWidth - mPopupWidth) / 2, 0);
        }
        else if (mode == PresentMode.ABOVE_LEFT) {
            popupView.showAsDropDown(rootView, 0, -mViewHeight - mPopupHeight);
        }
        else if (mode == PresentMode.ABOVE_RIGHT) {
            popupView.showAsDropDown(rootView, mViewWidth - mPopupWidth, -mViewHeight - mPopupHeight);
        }
        else if (mode == PresentMode.ABOVE_CENTER) {
            popupView.showAsDropDown(rootView, (mViewWidth - mPopupWidth) / 2, -mViewHeight - mPopupHeight);
        }
        else {
            popupView.showAsDropDown(rootView, 0, 0);
        }
    }

    /**
     * 关闭选项弹窗
     */
    public void closePopupView() {
        popupView.dismiss();
    }

    //endregion

    public static class PresentMode {
        //在视图的左下角弹出选项列表
        public final static int BELLOW_LEFT = 0;
        //在视图的下边居中位置弹出选项列表
        public final static int BELLOW_CENTER = 1;
        //在视图的右下角弹出选项列表
        public final static int BELLOW_RIGHT = 2;
        //在视图的左上角弹出选项列表
        public final static int ABOVE_LEFT = 3;
        //在视图的上边居中位置弹出选项列表
        public final static int ABOVE_CENTER = 4;
        //在视图的右上角弹出选项列表
        public final static int ABOVE_RIGHT = 5;
    }

    /**
     * 下拉框的子项数据
     */
    public static class Item {
        public String title;
        public Object value;

        public Item(String title) {
            this.title = title;
        }

        public Item(String title, Object value) {
            this.title = title;
            this.value = value;
        }

        public String getTitle() {
            return title;
        }

        public Item setTitle(String title) {
            this.title = title;
            return this;
        }

        public Object getValue() {
            return value;
        }

        public Item setValue(Object value) {
            this.value = value;
            return this;
        }
    }

    /**
     * 设置列表选项被选中事件
     * @param event 回调事件
     */
    public void setItemSelectedEvent(ItemSelectedEvent event) {
        this.mItemSelectedEvent = event;
    }

    private ItemSelectedEvent mItemSelectedEvent;

    public abstract static class ItemSelectedEvent {
        /**
         * 项目被选中
         *
         * @param item 项目数据
         * @param position 位置
         */
        public void onItemSelected(Item item, int position) {
        }

        /**
         * 选项弹窗被关闭
         */
        public void onPopupDismiss() {
        }
    }

    @Override
    public void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) {
        super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
        mViewWidth = newWidth;
        mViewHeight = newHeight;
    }
}
